package com.authine.cloudpivot.ext.applicationservice.v1.sourcing;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.applicationservice.v1.sourcing.vo.PushSXQuotationModel;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.inquiry.InquiryDto;
import com.authine.cloudpivot.ext.dto.system.OutApiClientDto;
import com.authine.cloudpivot.ext.utils.BigDecimalUtils;
import com.authine.cloudpivot.ext.utils.BoResultFormat;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.system.OutApiClientApiUtils;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.boot.json.JacksonJsonParser;
import org.springframework.http.*;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.cloudpivot.ext.utils.JdbcTemplateUtils.getTableName;

@Slf4j
public class PushSXQuotation extends ApplicationService {

    private static final NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);
    private static final String inquiryGoodsName = getTableName(ModelConst.T_INQUIRY_GOODS);
    private static final String quotationGoodsName = getTableName(ModelConst.T_QUOTATION_GOODS);
    final ObjectMapper objectMapper = new ObjectMapper();
    final RestTemplate restTemplate = new RestTemplate();

    //todo：推送松下报价
    public void pushQuotationGoodsToSx(@Parameter InquiryDto inquiryDto) {

        //询价单ID集合
        String inquiryId = inquiryDto.getInquiryId();

        //查询询价单id集合
        SingleResponse<BOList> listByIn = BoServiceUtils.findListBySimple(ModelConst.T_INQUIRY, "id", inquiryId);

        listByIn.getData().getData().forEach(i->{
            ArrayList<PushSXQuotationModel.PriceLines> pushQuotationModelList = new ArrayList<>();
            //根据clientId获取松下的报价
            BOList boList = new BOList();
            // 获取表名
            Map<String, Object> parameter = Maps.newHashMap();
            // 拼接sql
            StringBuilder totalSql = new StringBuilder();// 获取总数
            StringBuilder querySql = new StringBuilder();// 查询条件
            StringBuilder listSql = new StringBuilder();// 获取结果

            totalSql.append("select count(*) as count from (\n");
            totalSql.append("select qg.*,ig.* from \n");
            querySql.append(quotationGoodsName).append(" as qg\n");
            querySql.append("left join\n");
            querySql.append(inquiryGoodsName).append(" as ig\n");
            querySql.append("on qg.inquiry_goods_id=ig.id\n");
            querySql.append("where ig.inquiry_id = :inquiryId\n");
            querySql.append("and qg.quotation_goods_status=3\n");
            querySql.append("and qg.deleted=0\n");
            querySql.append("and ig.deleted=0\n");
            querySql.append("and ig.client_id='sino_ocean'\n");//暂时测试用
            querySql.append("order by ig.id asc,qg.price asc\n");
            parameter.put("inquiryId",i.get("id"));

            listSql.append("select qg.*,ig.* from \n");
            listSql.append(querySql);
            log.info("-------------------sql语句：{}-------------------", JSONObject.toJSONString(listSql.toString()));

            List<Map<String, Object>> result = jdbcTemplate.queryForList(listSql.toString(),parameter);
            log.info("-------------------result：{}-------------------", JSONObject.toJSONString(result));

            // 对结果进行格式化
            BoResultFormat.resultFormat(result, ModelConst.T_QUOTATION_GOODS, true);
            boList.setData(result);
            boList.setSchemaCode(ModelConst.T_QUOTATION_GOODS);
            log.info("-------------------boList：{}-------------------", JSONObject.toJSONString(boList));

            boList.getData().forEach(q->{
                PushSXQuotationModel.PriceLines pushQuotationModel = new PushSXQuotationModel.PriceLines();
                // 报价单价（如果税率>0，此处为含税单价）

                String tr = String.valueOf(q.get("tax_rate"));
                Double tax_rate = Double.parseDouble(tr);//税率
                //税前小计
                double pretax_amount = BigDecimalUtils.isNull(q.get("pretax_amount")).doubleValue();
                //小计
                double amount = BigDecimalUtils.isNull(q.get("amount")).doubleValue();
                Double unitPrice = tax_rate > 0 ? pretax_amount : amount;
                String clientInquiryGoodsId = String.valueOf(q.get("client_inquiry_goods_id"));
                String num = clientInquiryGoodsId.substring(clientInquiryGoodsId.lastIndexOf("_") + 1);
                pushQuotationModel.setNum(Integer.valueOf(num));
                pushQuotationModel.setUnitPrice(unitPrice);

                // 税率（实际税率*100）
                pushQuotationModel.setTaxRate(BigDecimalUtils.mul(tax_rate, 100).doubleValue());
                pushQuotationModel.setPriceID(q.get("id").toString());

                pushQuotationModel.setSupplierCommodityName(String.valueOf(q.get("name")));
                pushQuotationModel.setSupplierItemNum(q.get("id").toString());

                pushQuotationModelList.add(pushQuotationModel);
            });

            PushSXQuotationModel pushQuotationModels = new PushSXQuotationModel();
            pushQuotationModels.setRfxHeaderNum(String.valueOf(i.get("client_inquiry_id")));
            pushQuotationModels.setPriceLines(pushQuotationModelList);
            log.warn("[pushQuotationGoodsToFanWei] -- 推送{}条报价数据--->松下,报价信息:{}", pushQuotationModelList.size(), pushQuotationModels);

            try {
                String restResponse = pushSxQuotation(pushQuotationModels);
                log.warn("[punchoutApi.pushQuotationToSX] -- return:{}", restResponse);
            } catch (Exception e) {
//                GomroExceptionUtils.error(e, String.valueOf(inquiryIds));
                log.error("松下推送报价异常：{}，{}", e, inquiryId);
            }
        });
    }

    /**
     * 推送松下报价
     * @param pushSXQuotationModels 松下数据模型
     * @return
     */
    public String pushSxQuotation(PushSXQuotationModel pushSXQuotationModels) {
        OutApiClientDto outApiClient = OutApiClientApiUtils.getByGomroUsername("punchout_songxia");
        // 获取所有的 报价商品列表
        List<PushSXQuotationModel.PriceLines> collect = pushSXQuotationModels.getPriceLines().stream().sorted(Comparator.comparing(PushSXQuotationModel.PriceLines::getUnitPrice)).collect(Collectors.toList());
        pushSXQuotationModels.setPriceLines(Collections.singletonList(collect.get(0)));

        String client_id = outApiClient.getClient_id();
        String client_secret = outApiClient.getClient_secret();
        //client_credentials
        String grant_type = "client_credentials";
        //default
        String scope = "default";
        String tokenUrl = outApiClient.getToken_url();
        String quotationUrl = outApiClient.getResource_url();

        // 转换 json
        String quotationJson;
        try {
            quotationJson = objectMapper.writeValueAsString(pushSXQuotationModels);
            log.warn("松下推送报价请求JSON：{}", quotationJson);
        } catch (IOException e) {
            log.error("松下推送报价json转换异常：{}，{}", ExceptionUtils.getMessage(e), ExceptionUtils.getStackTrace(e));
            return null;
        }
        // 获取 Token
        MultiValueMap<String, String> param = new LinkedMultiValueMap<>();
        param.set("client_id", client_id);
        param.set("client_secret", client_secret);
        param.set("grant_type", grant_type);
        param.set("scope", scope);

        String tokenMsg;
        try {
            tokenMsg = restTemplate.postForObject(tokenUrl, param, String.class);
        } catch (Exception e) {
//            GomroExceptionUtils.error(e, String.valueOf(pushSXQuotationModels));
            log.error("松下推送报价token获取异常异常：{}，{}", ExceptionUtils.getMessage(e), ExceptionUtils.getStackTrace(e));
            return null;
        }
        if (null == tokenMsg) {
            return null;
        }
        JacksonJsonParser jsonParser = new JacksonJsonParser();
        String accessToken = jsonParser.parseMap(tokenMsg).get("access_token").toString();
        log.info("----------------------accessToken：{}------------------------", JSONObject.toJSONString(accessToken));

        // 调用推送报价接口
        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.AUTHORIZATION, accessToken);
        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        HttpEntity<String> entity = new HttpEntity<>(quotationJson, headers);

        ResponseEntity<String> exchange = restTemplate.exchange(quotationUrl, HttpMethod.POST, entity, String.class);

        log.warn("松下推送报价返回信息：{},{}", exchange.getStatusCode(), exchange.getBody());
        return exchange.getBody();
    }
}
